﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using HadronData;

namespace Hadron.Entities
{
    class Portal
        : Entity
    {
        private double m_dTime, m_dStateTime;
        private bool m_bExit, m_bOpen;
        private Circle m_circleContact;
        private float m_fState;
        private ParticleSystem m_particleSystem;

        public Portal(EntityMarker p_entityMarker, Environment p_environment, bool p_bExit)
            : base(p_entityMarker, p_environment)
        {
            m_circleContact = new Circle(p_entityMarker.Placement.Translation, 24.0f);
            m_circleBounds = m_circleContact;

            m_bOpen = false;
            m_fState = 0.0f;
            m_dStateTime = -1.0f; ;

            m_bExit = p_bExit;

            m_particleSystem = new ParticleSystem(512, 512.0f, 1.0f);
            m_particleSystem.ParticleColours = new Color[] { new Color(32, 32, 32), Color.Black };
            m_particleSystem.EmissionVelocityVariance = 48.0f;
        }

        public override void OnPlayerHit()
        {
            if (m_bExit && m_bOpen)
            {
                Open = false;
                m_environment.LevelComplete = true;
            }
        }

        public override void Update(GameTime p_gameTime)
        {
            m_dTime = p_gameTime.TotalGameTime.TotalSeconds;
            if (m_dStateTime < 0.0f)
                m_dStateTime = m_dTime;

            float fDeltaTime = (float) p_gameTime.ElapsedGameTime.TotalSeconds;

            if (m_bOpen)
            {
                m_fState = Math.Min(1.0f, m_fState + fDeltaTime * 2.0f);

                // if it's an entry portal, close automatically
                if (!m_bExit && m_dTime - m_dStateTime > 2.0)
                    Open = false;
            }
            else
                m_fState = Math.Max(0.0f, m_fState - fDeltaTime * 2.0f);

            m_particleSystem.Position = Position;
            m_particleSystem.Update(p_gameTime);
        }

        public override void Draw(SpriteBatch p_spriteBatch)
        {
            float fScale = 4.0f - m_fState * 3.0f;
            Color colour = new Color(Color.White, m_fState * m_fState * m_fState);
            Vector2 vecOrigin = new Vector2(64.0f, 64.0f);
            p_spriteBatch.Draw(AssetManager.Textures.Warp, Position, null, colour,
                (float) (m_dTime * MathHelper.Pi * 0.2f),
                vecOrigin, fScale, SpriteEffects.None, 0.0f);
            p_spriteBatch.Draw(AssetManager.Textures.Warp, Position, null, colour,
                (float)(m_dTime * MathHelper.Pi * 0.27f),
                vecOrigin, fScale, SpriteEffects.None, 0.0f);
            p_spriteBatch.Draw(AssetManager.Textures.Warp, Position, null, colour,
                (float)(m_dTime * MathHelper.Pi * 0.31f),
                vecOrigin, fScale, SpriteEffects.None, 0.0f);
            p_spriteBatch.Draw(AssetManager.Textures.Warp, Position, null, colour,
                (float)(m_dTime * MathHelper.Pi * 0.37f),
                vecOrigin, fScale, SpriteEffects.None, 0.0f);

            m_particleSystem.Draw(p_spriteBatch);
        }

        public override EntityType Type
        {
            get { return m_bExit ? EntityType.ExitPortal : EntityType.EntryPortal; }
        }

        public override bool Hostile
        {
            get { return false; }
        }

        public override bool Destructuble
        {
            get { return false; }
        }

        public override Geometry Geometry
        {
            get { return m_circleContact; }
        }

        public bool Open
        {
            get { return m_bOpen; }
            set
            {
                if (m_bOpen == value)
                    return;
                m_bOpen = value;
                m_particleSystem.Active = m_bOpen;
                if (m_dStateTime >= 0)
                    m_dStateTime = m_dTime;
                if (m_bOpen)
                    AssetManager.Sounds.WarpIn.Play();
                else
                    AssetManager.Sounds.WarpOut.Play();
            }
        }
    }
}
